<?php
/**
 * FastApp.
 * 7/27/24
 * @Author 深色的海 (wx:deepsea_0024)
 * @Contact telegram:deepsea159
 */

declare(strict_types=1);

namespace App\Fastapp\Listener;

use App\Fastapp\Api\Service\Account\WalletService;
use App\Fastapp\FastappEmailService;
use App\Fastapp\Job\WalletAddJob;
use App\Fastapp\Listener\Event\AccountBindEmailEvent;
use App\Fastapp\Listener\Event\AccountBindMobileEvent;
use App\Fastapp\Listener\Event\AccountDailyActiveEvent;
use App\Fastapp\Listener\Event\AccountLoginEvent;
use App\Fastapp\Listener\Event\AccountRegisterEvent;
use App\Fastapp\Listener\Event\AccountWithdrawalEvent;
use App\Fastapp\Model\Account;
use App\Fastapp\Model\AccountEventLog;
use App\Fastapp\Model\AccountLoginLog;
use App\Fastapp\Model\AccountSecurityKey;
use App\Fastapp\Model\AccountWithdrawal;
use Hyperf\Event\Annotation\Listener;
use Hyperf\Event\Contract\ListenerInterface;
use Psr\Container\ContainerInterface;
use Swoole\Coroutine;
use function Hyperf\Support\class_basename;

#[Listener]
class FastappListener implements ListenerInterface
{
    public function __construct(protected ContainerInterface $container)
    {
    }

    public function listen(): array
    {
        return [
            AccountLoginEvent::class,
            AccountWithdrawalEvent::class,
            AccountRegisterEvent::class,
            AccountBindEmailEvent::class,
            AccountBindMobileEvent::class,
            AccountDailyActiveEvent::class,
        ];
    }

    public function process(object $event): void
    {
        Coroutine::create(function () use ($event) {
            if ($event instanceof AccountDailyActiveEvent) {
                AccountEventLog::dailyActive($event->user_id, $event->event);
            } elseif ($event instanceof AccountLoginEvent) {
                Account::query()->where(['gene_id' => $event->user_id])->update(['last_ip' => $event->ip, 'last_at' => date('Y-m-d H:i:s')]);
                AccountLoginLog::query()->create([
                    'user_id' => $event->user_id,
                    'ip' => $event->ip,
                    'region' => $event->region,
                    'agent' => $event->agent,
                ]);
                FastappEmailService::sendLoginMsg($event->user_id, $event->agent);
            } elseif ($event instanceof AccountWithdrawalEvent) {
                $setting = api_cache()->getAppSetting($event->account_type);
                if (!empty($setting['withdrawal_check'])) return;
                $md = AccountWithdrawal::query()->where(['id' => $event->data_id, 'status' => 0])->first();
                if (!$md) return;
                if (bccomp($setting['withdrawal_check_amount'], $md->amount) != -1) return;
                $md->update(['status' => 1, 'pay_automatic' => 1]);
                WalletService::payOut($event->data_id);
            } elseif ($event instanceof AccountRegisterEvent) {
                AccountEventLog::dailyActive($event->user_id, class_basename($event));
                fastapp_queue_push(new WalletAddJob($event->user_id, $event->account_type, $event->symbol));
            } elseif ($event instanceof AccountBindEmailEvent) {
                Account::query()->where(['gene_id' => $event->user_id])->update(['email' => $event->email]);
                AccountSecurityKey::query()->firstOrCreate(['user_id' => $event->user_id, 'type' => 2, 'status' => 1]);
            } elseif ($event instanceof AccountBindMobileEvent) {
                Account::query()->where(['gene_id' => $event->user_id])->update(['code' => $event->code, 'mobile' => $event->mobile]);
                AccountSecurityKey::query()->firstOrCreate(['user_id' => $event->user_id, 'type' => 3, 'status' => 1]);
            }
        });
    }
}
